package org.clever.security.event;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.clever.common.utils.mapper.JacksonMapper;
import org.clever.security.Constant;
import org.clever.security.LoginModel;
import org.clever.security.client.UserLoginLogClient;
import org.clever.security.config.SecurityConfig;
import org.clever.security.dto.request.UserLoginLogAddReq;
import org.clever.security.entity.EnumConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 登录事件监听(写入登录成功的SessionID日志)
 * 作者： lzw<br/>
 * 创建时间：2018-09-18 13:55 <br/>
 */
@ConditionalOnProperty(prefix = Constant.ConfigPrefix, name = "login-model", havingValue = "session")
@Component
@Slf4j
public class LoginSuccessListener implements ApplicationListener<AuthenticationSuccessEvent> {

    @Autowired
    private SecurityConfig securityConfig;
    @Autowired
    private UserLoginLogClient userLoginLogClient;

    @SuppressWarnings("Duplicates")
    @Override
    public void onApplicationEvent(AuthenticationSuccessEvent event) {
        Authentication authentication = event.getAuthentication();
        if (LoginModel.jwt.equals(securityConfig.getLoginModel())) {
            log.info("### 登录成功 -> {}", authentication);
        } else {
            String loginIp = null;
            String sessionId = null;
            if (authentication.getDetails() != null && authentication.getDetails() instanceof WebAuthenticationDetails) {
                WebAuthenticationDetails webAuthenticationDetails = (WebAuthenticationDetails) authentication.getDetails();
                loginIp = webAuthenticationDetails.getRemoteAddress();
                sessionId = webAuthenticationDetails.getSessionId();
            } else {
                log.warn("### 登录成功未能得到SessionID [{}]", authentication.getName());
            }
            UserLoginLogAddReq userLoginLog = new UserLoginLogAddReq();
            userLoginLog.setSysName(securityConfig.getSysName());
            userLoginLog.setUsername(authentication.getName());
            userLoginLog.setLoginTime(new Date());
            userLoginLog.setLoginIp(StringUtils.trimToEmpty(loginIp));
            userLoginLog.setAuthenticationInfo(JacksonMapper.nonEmptyMapper().toJson(authentication));
            userLoginLog.setLoginModel(EnumConstant.ServiceSys_LoginModel_0);
            userLoginLog.setSessionId(StringUtils.trimToEmpty(sessionId));
            userLoginLog.setLoginState(EnumConstant.UserLoginLog_LoginState_1);
            try {
                userLoginLogClient.addUserLoginLog(userLoginLog);
                log.info("### 写入登录成功日志 [{}]", authentication.getName());
            } catch (Exception e) {
                log.error("写入登录成功日志失败 [{}]", authentication.getName(), e);
            }
        }
    }
}
